<?php
if(!defined('IN_WOGU')) {
    exit('Access Denied');
}

/**
* 翻页类
*
* @author     zhangwenbo
* @email      zhangwenbo_1986@163.com
* @qq         88433062
* @copyright  free
* @version    1.0[2010-12-04]
*/

class Pages
{
    protected $_page;

    protected $_perpage;

    protected $_total;

    protected $_length;

    protected $_offset;

    protected $_pages;

    protected $_classes = array(
        'core'       => 'core',
        'curr'       => 'curr',
        'normal'     => 'normal',
        'pre'        => 'pre',
        'next'       => 'next',
        'dots'       => 'dots',
        'jumper'     => 'jumper',
        'totalPages' => 'totalPages'
    );

    protected $_tags = array(
        'core'       => '<a href="%href" class="%class" %event>%page</a>',
        'prePage'    => '<div class="%class"><a href="%href" %event>上一页</a></div>',
        'nextPage'   => '<div class="%class"><a href="%href" class="%class" %event>下一页</a></div>',
        'dots'       => '<span class="%class">...</span>',
        'jumper'     => '<div class="%class"><input type="text" id="jumper"><input type="button" value="跳转" onclick="window.navigate(\'%href\' + document.getElementById(\'jumper\').value)"></div>',
        'totalPages' => '<div class="%class">共%page页</div>'
    );

    protected $_search = array('%class', '%page');

    protected $_ajax = array();

    protected $_output = '';

    /**
    * Construct function
    *
    * @param int $page - $page >= 1
    * @param int $total - $total >= 1
    * @param int $perpage - $perpage >= 1
    * @param int $length - $length >= 5 并且 $length >= $offset * 2 + (1 + 2)
    * @param int $offset - $offset >= 1
    */
    public function __construct($page, $total, $perpage, $length = 11, $offset = 4)
    {
        $this->_page = $page;
        $this->_perpage = $perpage;
        $this->_total = $total;
        $this->_length = $length;
        $this->_offset = $offset;

        $this->_pages = ceil($this->_total / $this->_perpage);

        if($this->_page > $this->_pages) {
            $this->_page = $this->_pages;
        }
    }

    public function setClass($key, $val)
    {
        $this->_classes[$key] = $val;

        return $this;
    }

    public function setTag($tag, $type = 'core')
    {
        $this->_tags[$type] = $tag;

        return $this;
    }

    public function setTags(array $options)
    {
        $this->_tags = array_merge($this->_tags, $options);

        return $this;
    }

    public function getTag($type = 'core')
    {
        if(empty($this->_ajax)) {
            $this->_tags[$type] = str_replace('%event', '', $this->_tags[$type]);
        } else {
            $event = $this->_ajax['event'] . '="' . $this->_ajax['func'] . '(%page)"';
            $this->_tags[$type] = str_replace('%event', $event, $this->_tags[$type]);
        }

        if(strpos($this->_tags[$type], '%href') !== false) {
            $requestUrl = trim($_SERVER['REQUEST_URI'], '?');
            if(empty($_SERVER['QUERY_STRING'])){
                $href = $requestUrl . '?page=%page';
            } else {
                if(isset($_GET['page'])) {
                    $href = preg_replace('/(.+page=)[^&]*(.*)/', '$1%page$2', $requestUrl);
                } else {
                    $href = $requestUrl . '&page=%page';
                }
            }

            $this->_tags[$type] = str_replace('%href', $href, $this->_tags[$type]);
        }

        return $this->_tags[$type];
    }

    public function createCore()
    {
        $tag = $this->getTag();
        $dotTag = str_replace('%class', $this->_classes['dots'], $this->getTag('dots'));

        if($this->_pages <= $this->_length) {
            $this->_output .= '<div class="'. $this->_classes['core'] .'">';

            for($i = 1; $i <= $this->_pages; $i++) {
                $class = $i == $this->_page ?  $this->_classes['curr'] :  $this->_classes['normal'];
                $this->_output .= str_replace($this->_search, array($class, $i), $tag);
            }

            $this->_output .= '</div>';

            return $this;
        }

        $from = $this->_page - $this->_offset;
        $to = $this->_page + $this->_offset;
        if($from <= 0) {
            $from = 1;
            $to = 2 * $this->_offset + 1;
        } elseif($to >= $this->_pages) {
            $to = $this->_pages;
            $from = $to - 2 * $this->_offset;
        }

        $preadd = $from - 1;
        $afteradd = $this->_pages - $to;
        $more = $this->_length - 2 * $this->_offset - 1;
        if($preadd > $afteradd) {
            if($afteradd > $more /2) {
                $afteradd = floor($more /2);
                $preadd = $more - $afteradd;
            } else {
                $preadd = $more - $afteradd;
            }
        } elseif($preadd <= $afteradd) {
            if($preadd > $more /2) {
                $preadd = floor($more /2);
                $afteradd = $more - $preadd;
            } else {
                $afteradd = $more - $preadd;
            }
        }

        $this->_output .= '<div class="'. $this->_classes['core'] .'">';

        if($preadd > 0) {
            for($i = 1; $i <= $preadd; $i++) {
                $this->_output .= str_replace($this->_search, array($this->_classes['normal'], $i), $tag);
            }

            if($preadd + 1 < $from) {
                $this->_output .= $dotTag;
            }
        }

        for($i = $from; $i <= $to; $i++) {
            $class = $i == $this->_page ? $this->_classes['curr'] : $this->_classes['normal'];
            $this->_output .=  str_replace($this->_search, array($class, $i), $tag);
        }

        if($afteradd > 0) {
            if($this->_pages - $afteradd + 1 > $to) {
                $this->_output .= $dotTag;
            }

            for($i = $afteradd; $i > 0; $i--) {
                $page = $this->_pages - $i + 1;
                $this->_output .= str_replace($this->_search, array($this->_classes['normal'], $page), $tag);
            }
        }

        $this->_output .= '</div>';

        return $this;
    }

    public function createPrePage()
    {
        $tag = $this->getTag('prePage');

        $prepage = max(($this->_page - 1), 1);

        $this->_output .= str_replace($this->_search, array($this->_classes['pre'], $prepage), $tag);

        return $this;
    }

    public function createNextPage($title = null)
    {
        $tag = $this->getTag('nextPage');

        $nextpage = min(($this->_page + 1), $this->_pages);

        $this->_output .= str_replace($this->_search, array($this->_classes['next'], $nextpage), $tag);

        return $this;
    }

    public function createJumper()
    {
        $tag = $this->getTag('jumper');
        $tag = str_replace($this->_search, array($this->_classes['jumper'], ''), $tag);

        $this->_output .= $tag;

        return $this;
    }

    public function createTotalPages()
    {
        $tag = $this->getTag('totalPages');
        $tag = str_replace($this->_search, array($this->_classes['totalPages'], $this->_pages), $tag);

        $this->_output .= $tag;

        return $this;
    }

    public function output()
    {
        return $this->_output;
    }

    public function normalOutput()
    {
        $this->createTotalPages()
        ->createPrePage()
        ->createCore()
        ->createNextPage()
        ->createJumper();

        return $this->output();
    }

    public function enableAjax($func = 'ajaxGet', $event = 'onclick')
    {
        $this->_ajax = array(
            'func'  => $func,
            'event' => $event
        );

        $this->setTag('jumper', '<div class="%class"><input type="text" id="jumper"><input type="button" value="跳转" %event></div>');

        return $this;
    }
}